package com.linko.soundrecorder;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;

/**
 * Created by zhongrz on 15-3-27.
 */
public class Recorder implements SharedPreferences.OnSharedPreferenceChangeListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
    public interface OnRecordListener {
        public void onStateChanged(int state);

        public void onError(int error);

        public void onNameChanged(String newName);
    }

    private static final String AUDIO_3GPP = "audio/3gpp";

    private static final String AUDIO_AMR = "audio/amr";

    private static final String AUDIO_ANY = "audio/*";

    private static final String ANY_ANY = "*/*";

    private static final String FILE_EXTENSION_AMR = ".amr";

    private static final String FILE_EXTENSION_3GPP = ".3gpp";
    private long mMaxFileSize = -1; // can be specified in the intent
    private String mRequestedType = AUDIO_ANY;

    private final String TAG = Recorder.class.getSimpleName();
    private Context mContext;
    private File mStorageFileDir = null;
    public static final String SAMPLE_DEFAULT_DIR = "sound_recorder";
    private String mExtension;
    private static String mRecordFileName;
    private OnRecordListener mRecodListener;

    public final static String ACTION_NAME = "action_type";
    public final static int ACTION_INVALID = 0;
    public final static int ACTION_START_RECORDING = 1;
    public final static int ACTION_STOP_RECORDING = 2;
    public final static int ACTION_SHOW_NOTI_START_RECORDING = 3;
    public final static int ACTION_HIDE_NOTI_START_RECORDING = 4;
    public final static int ACTION_SHOW_NOTI_STOP_RECORDING = 5;
    public final static String ACTION_PARAM_FORMAT = "format";
    public final static String ACTION_PARAM_SAMPLE_FILE = "sample_file";
    public final static String ACTION_PARAM_HIGH_QUALITY = "high_quality";
    public final static String ACTION_PARAM_MAX_FILE_SIZE = "max_file_size";

    private boolean isRequestRecord;

    public final int ERROR_NO_STORAGE_DEVICE = 0;
    public final int ERROR_STORAGE_FULL = 1;

    private File mSampleFile = null;

    public static final int IDLE_STATE = 0;

    public static final int RECORDING_STATE = 1;

    public static final int PLAYING_STATE = 2;

    public static final int PLAYING_PAUSED_STATE = 3;

    private static int mState = IDLE_STATE;

    private String mOldFileName;

    private SoundPool mSoundPool;
    private int mStartSound;
    private int mPauseSound;

    private AudioManager mAudioManager;

    private HashSet<String> mSavedRecord;

    private long mStartRecordTime = 0;
    private int mRecordTotalTime = 0;
    private Bundle mSavedInstanceState;

    public static final int NO_ERROR = 0;

    public static final int STORAGE_ACCESS_ERROR = 1;

    public static final int INTERNAL_ERROR = 2;

    public static final int IN_CALL_RECORD_ERROR = 3;
    private RecorderReceiver mRecorderReceiver;

    private static MediaPlayer mMediaPlayer;

    private SDCardMountEventReceiver mSDcardStateReceiver;

    public Recorder(Context context, Bundle savedInstanceState) {
        mSavedInstanceState = savedInstanceState;
        if (mSavedInstanceState != null) {
        }
        mContext = context;
        mStorageFileDir = new File(SettingsActivity.getPrefStoragePath(context));
        Log.i(TAG, "storage path:" + mStorageFileDir.getPath());
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
        settings.registerOnSharedPreferenceChangeListener(this);
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        mSoundPool = new SoundPool(5, AudioManager.STREAM_NOTIFICATION, 5);
        mPauseSound = mSoundPool.load(mContext, R.raw.soundrecord, 1);
        mStartSound = mSoundPool.load(mContext, R.raw.soundrecord, 1);
        mSavedRecord = new HashSet<String>();
    }

    public void onDestory() {
        mSoundPool.release();
        stopPlay();
    }

    public void onPause() {
        if (mRecorderReceiver != null) {
            mContext.unregisterReceiver(mRecorderReceiver);
        }
        unRegisterSDcardReceiver();
    }

    public void onResume() {
        mRecorderReceiver = new RecorderReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(RecordService.RECORDER_SERVICE_BROADCAST_NAME);
        mContext.registerReceiver(mRecorderReceiver, filter);
        if (!isFileExisted(mOldFileName)) {
            mSavedRecord.remove(getFileFullName());
        }
        registerSDcardReceiver();
    }

    private void registerSDcardReceiver() {
        mSDcardStateReceiver = new SDCardMountEventReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_MEDIA_EJECT);
        filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
        filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
        filter.addDataScheme("file");
        mContext.registerReceiver(mSDcardStateReceiver, filter);
    }

    private void unRegisterSDcardReceiver() {
        if (mSDcardStateReceiver != null) {
            mContext.unregisterReceiver(mSDcardStateReceiver);
        }
    }

    private class SDCardMountEventReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent == null) {
                return;
            }
            Log.i(TAG, "SD card state changed:" + intent.getAction());
            String storagePath = SettingsActivity.getPrefStoragePath(context);
            String dataStr = intent.getDataString();
            // if we set the storage path is internal,and the external storage device
            // mount or unmount,we do not something.
            if (!TextUtils.equals("file://" + storagePath, dataStr)) {
                return;
            }
            // reset all here because SD card state changed.
            reset();
        }
    }

    private void playActionSound(int soundId) {
        if (SettingsActivity.isEnabledSoundEffect(mContext)) {
            mSoundPool.play(mPauseSound, 1.0f, 1.0f, 0, 0, 1);
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (TextUtils.equals(key, SettingsActivity.KEY_RECORD_TYPE)) {
            String newType = sharedPreferences.getString(key, AUDIO_3GPP);
            mRequestedType = newType;
            renameExtension();
        } else if (TextUtils.equals(key, SettingsActivity.KEY_FILE_STORAGE_PATH)) {
            mStorageFileDir = new File(SettingsActivity.getPrefStoragePath(mContext));
        }
    }

    private void renameExtension() {
        String extension = "";
        if (AUDIO_AMR.equals(mRequestedType)) {
            extension = FILE_EXTENSION_AMR;
        } else if (AUDIO_3GPP.equals(mRequestedType)) {
            extension = FILE_EXTENSION_3GPP;
        }
        mExtension = extension;
    }

    public String getRequestedType() {
        return mRequestedType;
    }

    public void setOnRecordListener(OnRecordListener l) {
        mRecodListener = l;
    }

    /**
     * reset the record state.
     */
    public void reset() {
        resetFileName();
        mRecordTotalTime = 0;
        mStartRecordTime = 0;
        stopPlay();
        notifyStateChanged(IDLE_STATE);
    }

    /**
     * @param intent
     * @return whether the request formart we support.
     */
    public boolean processIntent(Intent intent) {
        isRequestRecord = false;
        if (intent != null) {
            String requsetType = intent.getType();
            if (AUDIO_AMR.equals(requsetType) || AUDIO_3GPP.equals(requsetType) || AUDIO_ANY.equals(requsetType) || ANY_ANY.equals(requsetType)) {
                mRequestedType = requsetType;
                isRequestRecord = true;
            } else {
                // not support,return false finish activity.
                if (requsetType != null) {
                    return false;
                }
            }
            final String EXTRA_MAX_BYTES = android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES;
            mMaxFileSize = intent.getLongExtra(EXTRA_MAX_BYTES, -1);
            if (mSavedInstanceState != null) {
                mMaxFileSize = mSavedInstanceState.getLong(SoundRecorder.MAX_FILE_SIZE_KEY);
            }
        }

        if (AUDIO_ANY.equals(mRequestedType)) {
            mRequestedType = SettingsActivity.getRecordType(mContext);
        } else if (ANY_ANY.equals(mRequestedType)) {
            mRequestedType = AUDIO_3GPP;
        }
        Log.i(TAG, "RequestedType:" + mRequestedType);
        return true;
    }

    public long getMaxLimitFileSize() {
        return mMaxFileSize;
    }

    public boolean syncStateWithService() {
        if (RecordService.isRecording()) {
            mState = RECORDING_STATE;
            mStartRecordTime = RecordService.getStartRecordTime();
            String path = RecordService.getFilePath();
            mExtension = path.substring(path.lastIndexOf("."), path.length());
            mStorageFileDir = new File(path.substring(0, path.lastIndexOf(SAMPLE_DEFAULT_DIR)));
            mOldFileName = mRecordFileName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));
            Log.i(TAG, "   sync state:"
                    + "\n   mState:" + mState
                    + "\n   mStartRecordTime:" + mStartRecordTime
                    + "\n   mStorageFileDir:" + mStorageFileDir.getPath()
                    + "\n   mRecordFileName:" + mRecordFileName
                    + "\n   mExtension:" + mExtension);
            notifyNameChanged(mRecordFileName);
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return is request record,like Mms or other app request record.
     */
    public boolean isRequestRecord() {
        return isRequestRecord;
    }

    public void resetFileName(String newName) {
        if (RecordService.isRecording()) {
            return;
        }

        if (TextUtils.isEmpty(newName)) {
            if (mOldFileName == null) {
                newName = getFromatedFileName();
            } else {
                newName = mOldFileName;
            }

        }
        if (isFileExisted(mRecordFileName)) {
            mContext.getContentResolver().delete(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "_data =?",
                    new String[]{getFileFullName()});
            String filePath = getFileFullName();
            mSavedRecord.remove(filePath);
            File file = new File(filePath);
            mRecordFileName = newName;
            file.renameTo(new File(getFileFullName()));
            saveRecordFile();
        }
        mRecordFileName = newName;
    }

    public void resetFileName() {
        renameExtension();
        mRecordFileName = getProperFileName(getFromatedFileName());
        Log.i(TAG, "record file name:" + mRecordFileName);
        if (mRecodListener != null) {
            mRecodListener.onNameChanged(mRecordFileName);
        }
    }

    public String getFromatedFileName() {
        SimpleDateFormat dataFormat = new SimpleDateFormat("MMHHmmss");
        return mContext.getString(R.string.recoding_prefix) + dataFormat.format(Calendar.getInstance().getTime());
    }

    private String getProperFileName(String fileName) {
        if (isFileExisted(fileName)) {
            int i = 2;
            while (true) {
                String temp = fileName + "(" + i + ")";
                if (!isFileExisted(temp)) {
                    fileName = temp;
                    break;
                }
                i++;
            }
        }
        return fileName;
    }

    public int getMaxAmplitude() {
        if (mState != RECORDING_STATE)
            return 0;
        return RecordService.getMaxAmplitude();
    }

    private boolean isFileExisted(String name) {
        String filePath = getStorageFileDir() + name + mExtension;
        File file = new File(filePath);
        return file.exists();
    }

    public String getFileWithExtension() {
        return mRecordFileName + mExtension;
    }

    public String getFileFullName() {
        return getStorageFileDir() + getFileWithExtension();
    }

    public static String getRecordFileName() {
        return mRecordFileName;
    }

    public String getStorageFileDir() {
        return mStorageFileDir.getPath() + File.separator + SAMPLE_DEFAULT_DIR + File.separator;
    }

    public void startRecord() {
        File file = new File(getStorageFileDir());
        if (file != null && !file.exists()) {
            boolean isSucc = file.mkdirs();
            if (!isSucc) {
                notifyErrorOccur(STORAGE_ACCESS_ERROR);
            }
        }
        stopAudioPlayback();
        mOldFileName = mRecordFileName;
        StorageHelper storageHelper = StorageHelper.getInstance(mContext);
        int outputfileformat = 0;
        boolean isHighQuality = SettingsActivity.isHighQuality(mContext);
        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            notifyErrorOccur(ERROR_NO_STORAGE_DEVICE);
            return;
        } else if (!storageHelper.diskSpaceAvailable()) {
            notifyErrorOccur(ERROR_STORAGE_FULL);
            return;
        } else {
            if (TextUtils.equals(mRequestedType, AUDIO_3GPP)) {
                outputfileformat = isHighQuality ? MediaRecorder.OutputFormat.AMR_WB
                        : MediaRecorder.OutputFormat.AMR_NB;
            } else if (TextUtils.equals(mRequestedType, AUDIO_AMR)) {
                outputfileformat = MediaRecorder.OutputFormat.THREE_GPP;
            } else {
                throw new IllegalArgumentException("Invalid output file type requested");
            }
        }
        Log.i(TAG, "===================================="
                + "\n  outputfileformat:" + outputfileformat
                + "\n  recod file path:" + getFileFullName()
                + "\n  isHighQuality:" + isHighQuality
                + "\n  MaxFileSize:" + mMaxFileSize
                + "\n====================================");
        Intent intent = new Intent(mContext, RecordService.class);
        intent.putExtra(ACTION_NAME, ACTION_START_RECORDING);
        intent.putExtra(ACTION_PARAM_FORMAT, outputfileformat);
        intent.putExtra(ACTION_PARAM_SAMPLE_FILE, getFileFullName());
        intent.putExtra(ACTION_PARAM_HIGH_QUALITY, isHighQuality);
        intent.putExtra(ACTION_PARAM_MAX_FILE_SIZE, mMaxFileSize);
        mContext.startService(intent);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        playActionSound(mStartSound);
    }

    /*
     * Make sure we're not recording music playing in the background, ask the
     * MediaPlaybackService to pause playback.
     */
    private void stopAudioPlayback() {
        // Shamelessly copied from MediaPlaybackService.java, which
        // should be public, but isn't.
        Intent i = new Intent("com.android.music.musicservicecommand");
        i.putExtra("command", "pause");
        mAudioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);
        mContext.sendBroadcast(i);
        try {
            Thread.sleep(300);
        } catch (InterruptedException ex) {
            Log.e(TAG, "sleep() for stop wait interrupted");
        }
    }

    public void stopRecord() {
        Intent intent = new Intent(mContext, RecordService.class);
        intent.putExtra(ACTION_NAME, ACTION_STOP_RECORDING);
        mContext.startService(intent);
        playActionSound(mPauseSound);
        mRecordTotalTime = (int) ((System.currentTimeMillis() - RecordService.getStartRecordTime()) / 1000);
    }

    public int getRecordTotalTime() {
        return mRecordTotalTime;
    }

    public void startPlay(float percentage) {
        if (mState == PLAYING_PAUSED_STATE) {
            mMediaPlayer.seekTo((int) (percentage * mMediaPlayer.getDuration()));
            mMediaPlayer.start();
            notifyStateChanged(PLAYING_STATE);
        } else {
            if (mMediaPlayer == null) {
                mMediaPlayer = new MediaPlayer();
                try {
                    mMediaPlayer.setDataSource(getFileFullName());
                    mMediaPlayer.setOnCompletionListener(this);
                    mMediaPlayer.setOnErrorListener(this);
                    mMediaPlayer.prepare();
                    mMediaPlayer.seekTo((int) (percentage * mMediaPlayer.getDuration()));
                    mMediaPlayer.start();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                    notifyErrorOccur(INTERNAL_ERROR);
                    mMediaPlayer = null;
                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                    notifyErrorOccur(INTERNAL_ERROR);
                    mMediaPlayer = null;
                    return;
                }
                notifyStateChanged(PLAYING_STATE);
            }
        }
    }

    public void pausePlay() {
        if (mMediaPlayer == null) {
            return;
        }
        mMediaPlayer.pause();
        notifyStateChanged(PLAYING_PAUSED_STATE);
    }

    public void stopPlay() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        notifyStateChanged(IDLE_STATE);
    }

    public boolean delete() {

        boolean isSucc = false;
        String filePath = getFileFullName();
        File file = new File(filePath);
        if (file.exists()) {
            mContext.getContentResolver().delete(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "_data =?",
                    new String[]{getFileFullName()});
            isSucc = file.delete();
            notifyStateChanged(IDLE_STATE);
            mContext.getContentResolver().notifyChange(
                    Uri.parse("content://media"), null);
        }
        return isSucc;
    }

    public static int getRecorderState() {
        return mState;
    }

    public long getRecordFileSize() {
        String fullName = getFileFullName();
        File file = new File(fullName);
        if (file.exists()) {
            return file.length();
        } else {
            return 0;
        }
    }

    public Uri saveRecordFile() {
        Uri uri = null;
        if (getRecordFileSize() == 0) {
            return null;
        }
        if (!mSavedRecord.contains(getFileFullName()) && getRecorderState() != RECORDING_STATE) {
            uri = addToMediaDB(new File(getFileFullName()));
            mSavedRecord.add(getFileFullName());
        }
        return uri;
    }

    private Uri addToMediaDB(File file) {
        Resources res = mContext.getResources();
        ContentValues cv = new ContentValues();
        long current = System.currentTimeMillis();
        long modDate = file.lastModified();
        long sampleLengthMillis = getRecordTotalTime() * 1000L;
        String title = mRecordFileName;
        // Lets label the recorded audio file as NON-MUSIC so that the file
        // won't be displayed automatically, except for in the playlist.
        cv.put(MediaStore.Audio.Media.IS_MUSIC, "0");
        cv.put(MediaStore.Audio.Media.TITLE, title);
        cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
        cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
        cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
        cv.put(MediaStore.Audio.Media.DURATION, sampleLengthMillis);
        cv.put(MediaStore.Audio.Media.MIME_TYPE, mRequestedType);
        cv.put(MediaStore.Audio.Media.ARTIST, res.getString(R.string.audio_db_artist_name));
        cv.put(MediaStore.Audio.Media.ALBUM, res.getString(R.string.audio_db_album_name));
        Log.d(TAG, "Inserting audio record: " + cv.toString());
        ContentResolver resolver = mContext.getContentResolver();
        Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        Log.d(TAG, "ContentURI: " + base);
        Uri result = resolver.insert(base, cv);
        if (result == null) {
            Log.w(TAG, mContext.getString(R.string.error_mediadb_new_record));
            return null;
        }

        if (getPlaylistId(res) == -1) {
            createPlaylist(res, resolver);
        }
        int audioId = Integer.valueOf(result.getLastPathSegment());
        addToPlaylist(resolver, audioId, getPlaylistId(res));

        // Notify those applications such as Music listening to the
        // scanner events that a recorded audio file just created.
        mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
        return result;
    }

    /*
     * Obtain the id for the default play list from the audio_playlists table.
     */
    private int getPlaylistId(Resources res) {
        Uri uri = MediaStore.Audio.Playlists.getContentUri("external");
        final String[] ids = new String[]{
                MediaStore.Audio.Playlists._ID
        };
        final String where = MediaStore.Audio.Playlists.NAME + "=?";
        final String[] args = new String[]{
                res.getString(R.string.audio_db_playlist_name)
        };
        Cursor cursor = query(uri, ids, where, args, null);
        if (cursor == null) {
            Log.v(TAG, "query returns null");
        }
        int id = -1;
        if (cursor != null) {
            cursor.moveToFirst();
            if (!cursor.isAfterLast()) {
                id = cursor.getInt(0);
            }
            cursor.close();
        }
        return id;
    }

    /*
     * A simple utility to do a query into the databases.
     */
    private Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                         String sortOrder) {
        try {
            ContentResolver resolver = mContext.getContentResolver();
            if (resolver == null) {
                return null;
            }
            return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
        } catch (UnsupportedOperationException ex) {
            return null;
        }
    }

    /*
     * Create a playlist with the given default playlist name, if no such
     * playlist exists.
     */
    private Uri createPlaylist(Resources res, ContentResolver resolver) {
        ContentValues cv = new ContentValues();
        cv.put(MediaStore.Audio.Playlists.NAME, res.getString(R.string.audio_db_playlist_name));
        Uri uri = resolver.insert(MediaStore.Audio.Playlists.getContentUri("external"), cv);
        if (uri == null) {
            Toast.makeText(mContext, R.string.error_mediadb_new_record, Toast.LENGTH_LONG).show();
        }
        return uri;
    }

    /*
   * Add the given audioId to the playlist with the given playlistId; and
   * maintain the play_order in the playlist.
   */
    private void addToPlaylist(ContentResolver resolver, int audioId, long playlistId) {
        String[] cols = new String[]{
                "count(*)"
        };
        Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
        Cursor cur = resolver.query(uri, cols, null, null, null);
        cur.moveToFirst();
        final int base = cur.getInt(0);
        cur.close();
        ContentValues values = new ContentValues();
        values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + audioId));
        values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audioId);
        resolver.insert(uri, values);
    }

    public int getProgress() {
        if (mState == RECORDING_STATE) {
            return (int) ((System.currentTimeMillis() - RecordService.getStartRecordTime()) / 1000);
        } else if (mState == IDLE_STATE) {
            return mRecordTotalTime;
        } else if (mState == PLAYING_STATE || mState == PLAYING_PAUSED_STATE) {
            return (int) (getplayPercentage() * mRecordTotalTime);
        }
        return 0;
    }

    public void showNotification() {
        Intent intent = new Intent(mContext, RecordService.class);
        intent.putExtra(ACTION_NAME, ACTION_SHOW_NOTI_START_RECORDING);
        mContext.startService(intent);
    }

    public void hideNotification() {
        Intent intent = new Intent(mContext, RecordService.class);
        intent.putExtra(ACTION_NAME, ACTION_HIDE_NOTI_START_RECORDING);
        mContext.startService(intent);
    }

    private class RecorderReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.hasExtra(RecordService.RECORDER_SERVICE_BROADCAST_PHONE_STATE)) {
                Log.i(TAG, "onReceive:" + "RECORDER_SERVICE_BROADCAST_PHONE_STATE");
                int phoneState = intent.getIntExtra(
                        RecordService.RECORDER_SERVICE_BROADCAST_PHONE_STATE,
                        TelephonyManager.CALL_STATE_IDLE);
                if (phoneState != TelephonyManager.CALL_STATE_IDLE) {
                    if (mState == Recorder.RECORDING_STATE) {
                        boolean isKeepRecording = SettingsActivity.isKeepRecordingWhenCalling(context);
                        if (!isKeepRecording) {
                            stopRecord();
                        }
                    }
                }
            }
            if (intent.hasExtra(RecordService.RECORDER_SERVICE_BROADCAST_STATE)) {
                Log.i(TAG, "onReceive:" + "RECORDER_SERVICE_BROADCAST_STATE");

                boolean isRecording = intent.getBooleanExtra(RecordService.RECORDER_SERVICE_BROADCAST_STATE, false);
                mState = isRecording ? Recorder.RECORDING_STATE : Recorder.IDLE_STATE;
                if (!isRecording) {
                    saveRecordFile();
                }
                if (!isActivityVisable(mContext)) {
                    return;
                }
                notifyStateChanged(mState);
            }
            if (intent.hasExtra(RecordService.RECORDER_SERVICE_BROADCAST_ERROR)) {
                Log.i(TAG, "onReceive:" + "RECORDER_SERVICE_BROADCAST_ERROR");
                stopRecord();
                int error = intent.getIntExtra(RecordService.RECORDER_SERVICE_BROADCAST_ERROR, 0);
                if (!isActivityVisable(mContext)) {
                    return;
                }
                notifyErrorOccur(error);
            }
        }
    }

    public static boolean isActivityVisable(final Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
        if (!tasks.isEmpty()) {
            ComponentName topActivity = tasks.get(0).topActivity;
            String className = topActivity.getClassName();
            if (TextUtils.equals(className, SoundRecorder.class.getName())) {
                return true;
            }
        }
        return false;
    }

    public float getplayPercentage() {
        if (mMediaPlayer != null) {
            return ((float) mMediaPlayer.getCurrentPosition()) / mMediaPlayer.getDuration();
        }
        return 0.0f;
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        stopPlay();
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i2) {
        Log.i(TAG, "play occur error:" + i + "," + i2);
        notifyErrorOccur(INTERNAL_ERROR);
        return true;
    }

    private void notifyStateChanged(int state) {
        mState = state;
        if (mRecodListener != null) {
            mRecodListener.onStateChanged(state);
        }
    }

    private void notifyErrorOccur(int error) {
        if (mRecodListener != null) {
            mRecodListener.onError(error);
        }
    }

    private void notifyNameChanged(String newName) {
        if (mRecodListener != null) {
            mRecodListener.onNameChanged(newName);
        }
    }
}
